package javaLearning.Steam流式;

import java.time.LocalDateTime;
import java.time.Month;
import java.util.*;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static java.util.stream.Collectors.groupingBy;

/**
 * @description: 流失编程应用一
 * @author: Kk
 * @create: 2020-12-03 17:14
 **/
public class Demo1 {

    public static void init(List<User> userList){
        Random random=new Random();
        for (int i=0;i<5;i++){
            User user = new User();
            user.setId(i);
            user.setName("Tom-"+i);
            user.setAge(random.nextInt(30));
            user.setBirth(LocalDateTime.of(2020, Month.DECEMBER,1+random.nextInt(30),random.nextInt(24),random.nextInt(60)));
            userList.add(user);
        }
    }

    public static void main(String[] args) {
        List<User> userList =new ArrayList<>();
        //初始化原始数据
        init(userList);

        //去重操作
        Demo1.distinctList(userList);

        //过滤操作
        //Demo1.filterList(userList);

        //排序操作
        //Demo1.sortList(userList);

        //截断流操作 limit
        //Demo1.limitList(userList);

        //跳过元素
        //Demo1.skipList(userList);

        //map单一流转换并输出（转换元素,转换成新的元素）
        //Demo1.toMapList(userList);

        //flatMap合并多个流，再输出
        //Demo1.toFlatmapList(userList);

        //终端流 内部迭代forEach、收集、将流转换为其他形式collect
        //演示collect
        //Demo1.collectList(userList);
    }

    /**
     * 其他终端操作：
     *
     * boolean allMatch(Predicate<? super T> predicate); 检查是否匹配所有元素。
     * boolean anyMatch(Predicate<? super T> predicate); 检查是否至少匹配一个元素。
     * boolean noneMatch(Predicate<? super T> predicate); 检查是否没有匹配所有元素。
     * Optional<T> findFirst(); 返回当前流中的第一个元素。
     * Optional<T> findAny(); 返回当前流中的任意元素。
     * long count(); 返回流中元素总数。
     * Optional<T> max(Comparator<? super T> comparator); 返回流中最大值。
     * Optional<T> min(Comparator<? super T> comparator); 返回流中最小值。
     * T reduce(T identity, BinaryOperator<T> accumulator); 可以将流中元素反复结合起来，得到一个值。 返回 T。这是一个归约操作。
     */
    private static void collectList(List<User> userList) {
        //两种方式
        //每个map存放的是一个value
        Map<String, User> collect = userList.stream()
                .collect(Collectors.toMap(User::getName, Function.identity(), (user1, user2) -> user2));
        System.out.println(collect);

        //每个map元素存放的是数组
        Map<String, List<User>> collect1 = userList.stream()
                .collect(groupingBy(User::getName));
        System.out.println(collect1);
    }

    /**
     * flatMap方法返回的是一个stream，flatMap将流中的当前元素替换为此返回流拆解的流元素；
     * @param userList
     */
    private static void toFlatmapList(List<User> userList) {
        userList.stream()
                .flatMap(user -> Stream.of(user.getName()))
                .forEach(System.out::println);
    }

    /**
     * 改变元素
     * @param userList
     */
    private static void toMapList(List<User> userList) {
        userList.stream()
                .map(User::getName)
                .forEach(System.out::println);

    }

    /**
     * 跳过元素
     * @param userList
     */
    private static void skipList(List<User> userList) {
        userList.stream()
                .skip(2)
                .forEach(user -> System.out.println(user.getName()+"  "+user.getAge()));
    }

    /**
     * limit截断
     * @param userList
     */
    private static void limitList(List<User> userList) {
        //截断流，使其元素不超过给定数量。如果元素的个数小于maxSize，那就获取所有元素
        userList.stream()
                .sorted((o1, o2) -> o2.getAge()-o1.getAge()).limit(2) //降序
                .forEach(user -> System.out.println(user.getName()+"  "+user.getAge()));
    }

    /**
     * 排序
     * @param userList
     */
    private static void sortList(List<User> userList) {
        //排序
        userList.stream()
                //.sorted(Comparator.comparing(User::getAge))
                //.sorted((o1, o2) -> o1.getAge()-o2.getAge()) //升序
                .sorted((o1, o2) -> o2.getAge()-o1.getAge()) //降序
                .forEach(user -> System.out.println(user.getName()+"  "+user.getAge()));
    }

    /**
     * 过滤
     * @param userList
     */
    private static void filterList(List<User> userList) {
        userList.stream()
                .filter(user -> user.getAge()>15)
                .forEach(user -> System.out.println(user.getName()+"  "+user.getAge()));
    }

    /**
     * 去重
     * @param userList
     */
    private static void distinctList(List<User> userList) {
        //添加两个一样名字的User
        User user=new User();
        user.setName("lkx");
        userList.add(user);
        user.setAge(111);
        User user1=new User();
        user1.setName("lkx");
        user1.setAge(123);
        userList.add(user1);

        userList.forEach(u -> {
            System.out.println(u.getName());
        });
        System.out.println("=======");
        //去除同名的多余user
        userList.stream().distinct().forEach(u -> {
            System.out.println(u.getName());
        });

        //还原
        userList.remove(user);
        userList.remove(user);
    }


}
